import Vue from "vue"
import VueRouter from "vue-router"
import store from "@/store"



//懒加载引入路由组件
const Home = ()=>import("@pages/Home")
const Login = ()=>import("@pages/Login")
const Register = ()=>import("@pages/Register")
const Search = ()=>import("@pages/Search")
const Detail = ()=>import("@pages/Detail")
const AddCartSuccess = ()=>import("@pages/AddCartSuccess")
const ShopCart = ()=>import("@pages/ShopCart")
const Pay = () => import("@pages/Pay");
const PaySuccess = () => import("@pages/PaySuccess");
const Trade = () => import("@pages/Trade");
const Center = () => import("@pages/Center");



Vue.use(VueRouter)

//因为编程式路由导航在多次点击时会重新报错（push方法放在了VueRouter的原型对象上）
//原因：this.$router.push方法返回一个promise，在多次点击时，会返回失败的promise，而原始代码中的push方法接收三个参数，第一个参数是跳转的路由地址，第二个参数是处理成功promise的回调函数，第三个参数是处理失败promise的回调函数，处理失败和成功的参数默认都是undefined，需要在编程路由导航调用push方法时传入两个回调函数才不会报错，还有一种方法就是重写push
//解决方法：重写一个push,给我们自己写的push的第二个参数和第三个参数设置默认值为一个回调函数
//原来push方法中的this指向VueRouter的实例，但是现在lastPush被直接默认调用,所以this就指向了undefined了,内部很可能出错，所以要把this修改为VueRouter的实例再调用
const lastPush = VueRouter.prototype.push
VueRouter.prototype.push = function(location,onComplete=()=>{},onAbort=()=>{}){
    return lastPush.call(this,location,onComplete,onAbort)
}
const router = new VueRouter({
    scrollBehavior () {
        return{
            x:0,
            y:0
        }
    },
    mode:"history",
    routes:[
        {
            path:"/home",
            component:Home,
            name:"home"
        },
        {
            path:"/login",
            component:Login,
            name:"login",
            meta:{
                footerIsHidden:true
            },
            beforeEnter(to,from,next){
                if(localStorage.getItem('user_token')){
                    //如果有token，就是登录状态，就不让进登录页，返回home页
                    next("/home")
                }else{
                    next()
                }
            }
        },
        {
            path:"/register",
            component:Register,
            name:"register",
            meta:{
                footerIsHidden:true
            }
        },
        {
            path:"/search/:keyword?",
            component:Search,
            name:"search"
        },
        {
            path:"/detail/:skuId",
            component:Detail,
            name:"detail"
        },
        {
            path:'/addcartsuccess',
            component:AddCartSuccess,
            name:'addcartsuccess',
            // 路由独享守卫，进入购物车成功页面必须要用成功的数据才能进来，否则就进入购物车页面
            beforeEnter(to,from,next){
                if(sessionStorage.getItem("cartData")){
                    next()
                }else{
                    next("/shopcart")
                }
            }
        },
        {
            path:'/shopcart',
            component:ShopCart,
            name:"shopcart"
        },
        {
            path: "/pay",
            component: Pay,
            name: "pay",
          },
          {
            path: "/paysuccess",
            component: PaySuccess,
            name: "paysuccess",
          },
          {
            path: "/trade",
            component: Trade,
            name: "trade",
          },
          {
            path: "/center",
            component: Center,
            name: "center",
          },
        {
            path:"/",
            redirect:"/home"
        }
    
    ]



})



router.beforeEach((to,from,next)=>{
    //定义一个数组，保存所有必须有token才能访问的路由地址
const checkPath = ["/center","/pay","/paysuccess","/trade"]
//因为to中有一个属性path，是要去的路由的路由地址
//得到当前to的地址是否在checkpath中,some返回布尔值，有一个满足条件就为true
const isCheckPath = checkPath.some((item)=>{
    //判断to.path 是否以 item为开头(考虑多级路由的请求)
    return to.path.startsWith(item)
})


/* 
    to:要去的路由对象
    from:来源的路由对象
    next:决定下一步的操作
      - next():直接放行,去往to的路由地址
      - next("/login"):不再去往to的地址,而是去往next规定的地址
  */
 //获取vuex的token和用户名
 const token = store.state.user.token//登录时只获取了token
 const nickName =store.state.user.nickName
 //1.如果有用户名，肯定是登录状态,直接放行
 if(nickName){
    return next()
}
//2.判断当前路由地址是否需要进行token校验
if(isCheckPath){
    //当前路径需要token校验
    //首先判断是否拥有token
    if(token){
        //如果有token,发送获取用户名请求,并放行
        //因为这不是在路由中，不能使用辅助函数获取actions，要使用dispatch
        store.dispatch("user/getUserInfo")
        next()
    }else{
    //没有token就去登录页
    next('/login')
    }
}else{
    //当前路径不需要token校验（但是如果你是登录状态访问不需要token校验的路由，也可以获取一下用户名，可以让登录的dom元素在登录之后显示你的用户信息）
    if (token) {
        store.dispatch("user/getUserInfo");
      }
    next()
}

})


export default router